package org.example;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 说明:这是一个io密集型任务.
 * 生成一个1GB的文件,然后将它复制8份到output目录下
 */
public class IOIntensiveTask {
    // 配置参数
    private static final int THREAD_COUNT = 8;          // 并发线程数
    private static final int copyFileBufferSize = 10; // 缓冲区大小 1MB
    private static final int genFileBufferSize = 1024 * 1024; //生成文件的缓存大小1Mb
    private static String SRC_FILE = null;  // 源文件（需提前生成）
    private static String DEST_DIR = null;   // 输出目录

    public static void main(String[] args) throws Exception {
        System.out.println("这是一个io密集型任务的模拟,会在当前目录下生成一个1GB的文件," +
                "然后将它复制到当前目录下的output目录中");

        String format = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String filePrefix = "genFile";
        String property = System.getProperty("user.dir");
        SRC_FILE=property +File.separator + filePrefix+format +".data";
        System.out.println("生成的文件是:"+SRC_FILE);
        DEST_DIR=property +File.separator + "output";
        System.out.println("复制的目录是:"+DEST_DIR);
        File file = new File(DEST_DIR);
        if (!file.exists()) {
            file.mkdirs();
        }
        // 创建测试文件（1GB）
        createTestFile(SRC_FILE, 1024 ); // 1G大小
        System.out.println("数据已造好");
//        createTestFile(SRC_FILE, 2); // 1024MB

        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
        long startTime = System.currentTimeMillis();

        // 每个线程复制文件到不同目标
        for (int i = 0; i < THREAD_COUNT; i++) {
            final String destPath = DEST_DIR+File.separator +filePrefix+format+ "_copy_" + i + ".bin";
            executor.submit(() -> copyFile(SRC_FILE, destPath));
        }

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.HOURS);

        long duration = System.currentTimeMillis() - startTime;
        System.out.printf("总耗时: %.2f 秒%n", duration / 1000.0);
        System.out.printf("总数据量: %.2f GB%n", (THREAD_COUNT * 1024) / 1024.0);
        System.out.printf("吞吐量: %.2f MB/s%n", (THREAD_COUNT * 1024 * 1000.0) / (duration * 1.0));
    }

    // 生成测试文件
    private static void createTestFile(String path, int sizeMB) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(path);
             BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            byte[] buffer = new byte[genFileBufferSize];
            for (int i = 0; i < sizeMB; i++) {
                bos.write(buffer);
            }
        }
    }

    // 文件复制方法（带缓冲）
    private static void copyFile(String src, String dest) {
        try (InputStream fileInputStream = new FileInputStream(src);
//             BufferedInputStream bis = new BufferedInputStream(fileInputStream, BUFFER_SIZE);
             OutputStream fileOutputStream = new FileOutputStream(dest);
//             BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream, BUFFER_SIZE)
        ) {

            byte[] buffer = new byte[copyFileBufferSize];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            System.err.println("文件操作失败: " + e.getMessage());
        }
    }
}